/**
 * 
 */
package com.roc.util;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import org.apache.log4j.Logger;
import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipOutputStream;

/**
 * @author dxpeng
 * 
 */
public class ZipUtils {
	static final Logger logger = Logger.getLogger(ZipUtils.class);
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		
			//new ZipUtils("e:\\test").doZip("e:\\test", "e:\\test\\我.zip");
			new ZipUtils("e:\\test\\分润.zip").compress("e:\\test");
		
	}

	static final int BUFFER = 8192;

	private File zipFile;

	public ZipUtils(String pathName) {
		zipFile = new File(pathName);
	}

	//appach ant.jar 压缩文件
	public void compress(String srcPathName) {
		File file = new File(srcPathName);
		if (!file.exists()){
			logger.error("###########"+srcPathName+"不存在！##########");
			throw new RuntimeException(srcPathName + "不存在！");
		}
			
		
		try {
			FileOutputStream fileOutputStream = new FileOutputStream(zipFile);
			/*CheckedOutputStream cos = new CheckedOutputStream(fileOutputStream,
					new CRC32());*/
			ZipOutputStream out = new ZipOutputStream(fileOutputStream);
			out.setEncoding(Utils.getConfigValue("zip_encode"));
			String basedir = "";
			compress(file, out, basedir);
			out.close();
		} catch (Exception e) {
			logger.error("###########压缩文件出错["+e.getMessage()+"]##########");
			throw new RuntimeException(e);
		}
	}

	private void compress(File file, ZipOutputStream out, String basedir) {
		/* 判断是目录还是文件 */
		if (file.isDirectory()) {
			logger.info("###########压缩：" + basedir + file.getName());
			this.compressDirectory(file, out, basedir);
		} else {
			logger.info("###########压缩：" + basedir + file.getName());
			this.compressFile(file, out, basedir);
		}
	}

	/** 压缩一个目录 */
	private void compressDirectory(File dir, ZipOutputStream out, String basedir) {
		if (!dir.exists())
			return;

		File[] files = dir.listFiles();
		for (int i = 0; i < files.length; i++) {
			/* 递归 */
			compress(files[i], out, basedir + dir.getName() + "/");
		}
	}

	/** 压缩一个文件 */
	private void compressFile(File file, ZipOutputStream out, String basedir) {
		if (!file.exists()) {
			return;
		}
		try {
			BufferedInputStream bis = new BufferedInputStream(
					new FileInputStream(file));
			ZipEntry entry = new ZipEntry(basedir + file.getName());
			out.putNextEntry(entry);
			int count;
			byte data[] = new byte[BUFFER];
			while ((count = bis.read(data, 0, BUFFER)) != -1) {
				out.write(data, 0, count);
			}
			bis.close();
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	// java jdk自带压缩
	public File doZip(String sourceDir, String zipFilePath) throws IOException {

		File file = new File(sourceDir);
		File zipFile = new File(zipFilePath);
		java.util.zip.ZipOutputStream zos = null;
		try {
			// 创建写出流操作
			OutputStream os = new FileOutputStream(zipFile);
			BufferedOutputStream bos = new BufferedOutputStream(os);
			zos = new java.util.zip.ZipOutputStream(bos);
			
			String basePath = null;

			// 获取目录
			if (file.isDirectory()) {
				basePath = file.getPath();
			} else {
				basePath = file.getParent();
			}

			zipFile(file, basePath, zos);
		} finally {
			if (zos != null) {
				zos.closeEntry();
				zos.close();
			}
		}

		return zipFile;
	}

	/**
	 * @param source
	 *            源文件
	 * @param basePath
	 * @param zos
	 */
	private void zipFile(File source, String basePath,
			java.util.zip.ZipOutputStream zos) throws IOException {
		File[] files = null;
		if (source.isDirectory()) {
			files = source.listFiles();
		} else {
			files = new File[1];
			files[0] = source;
		}

		InputStream is = null;
		String pathName;
		byte[] buf = new byte[1024];
		int length = 0;
		try {
			for (File file : files) {
				if (file.isDirectory()) {
					pathName = file.getPath().substring(basePath.length() + 1)
							+ "/";
					System.out.println(pathName);
					zos.putNextEntry(new ZipEntry(pathName));
					zipFile(file, basePath, zos);
				} else {
					pathName = file.getPath().substring(basePath.length() + 1);
					System.out.println("--:"+pathName);
					is = new FileInputStream(file);
					BufferedInputStream bis = new BufferedInputStream(is);
					zos.putNextEntry(new ZipEntry(pathName));
					while ((length = bis.read(buf)) > 0) {
						zos.write(buf, 0, length);
					}
				}
			}
		} finally {
			if (is != null) {
				is.close();
			}
		}

	}

}
